diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index 5330942..851786d 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -886,9 +886,12 @@ class ServerNode(PGChildNodeView): if server is None: return bad_request(gettext("Server not found.")) - # Fetch User Details. - user = User.query.filter_by(id=current_user.id).first() - if user is None: + if current_user and hasattr(current_user, 'id'): + # Fetch User Details. + user = User.query.filter_by(id=current_user.id).first() + if user is None: + return unauthorized(gettext("Unauthorized request.")) + else: return unauthorized(gettext("Unauthorized request.")) data = request.form if request.form else json.loads( diff --git a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css index 5300189..f0b12e3 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css +++ b/web/pgadmin/browser/server_groups/servers/databases/templates/databases/css/database.css @@ -9,6 +9,6 @@ .icon-database-not-connected { background-image: url('{{ url_for('NODE-database.static', filename='img/databasebad.svg') }}') !important; - border-radius: 10px + border-radius: 10px; background-size: 20px !important; } diff --git a/web/pgadmin/static/css/bootstrap.overrides.css b/web/pgadmin/static/css/bootstrap.overrides.css index b0c531a..d2936a7 100755 --- a/web/pgadmin/static/css/bootstrap.overrides.css +++ b/web/pgadmin/static/css/bootstrap.overrides.css @@ -1438,3 +1438,9 @@ body { .multi-checkbox .check.partial:after { content: "\003F"; } + +/* Override default bootstrap popover fonts & size */ +.popover-content { + font-family: 'Open Sans'; + font-size: 13px; +} diff --git a/web/pgadmin/static/js/sqleditor_utils.js b/web/pgadmin/static/js/sqleditor_utils.js index 876aa52..f77acc8 100644 --- a/web/pgadmin/static/js/sqleditor_utils.js +++ b/web/pgadmin/static/js/sqleditor_utils.js @@ -8,8 +8,8 @@ ////////////////////////////////////////////////////////////////////////// // This file contains common utilities functions used in sqleditor modules -define(['jquery'], - function ($) { +define(['jquery', 'sources/gettext'], + function ($, gettext) { var sqlEditorUtils = { /* Reference link http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript * Modified as per requirement. @@ -55,6 +55,125 @@ define(['jquery'], }, capitalizeFirstLetter: function (string) { return string.charAt(0).toUpperCase() + string.slice(1); + }, + // Status flag + previousStatus: null, + // This function will fetch the connection status via ajax + fetchConnectionStatus: function(url, $el, $status_el) { + $.ajax({ + url: url, + method: 'GET', + success: function (res) { + if(res && res.data) { + var status = res.data.status, + msg = res.data.message, + is_status_changed = false; + + // Inject CSS as required + switch(status) { + // Busy + case 1: + // if received busy status more than once then only + if(status == sqlEditorUtils.previousStatus && + !$status_el.hasClass('fa-hourglass-half')) { + $status_el.removeClass() + .addClass('fa fa-hourglass-half'); + is_status_changed = true; + } + break; + // Idle in transaction + case 2: + if(sqlEditorUtils.previousStatus != status && + !$status_el.hasClass('fa-clock-o')) { + $status_el.removeClass() + .addClass('fa fa-clock-o'); + is_status_changed = true; + } + break; + // Failed in transaction + case 3: + if(sqlEditorUtils.previousStatus != status && + !$status_el.hasClass('fa-exclamation-circle')) { + $status_el.removeClass() + .addClass('fa fa-exclamation-circle'); + is_status_changed = true; + } + break; + // Failed in transaction with unknown server side error + case 4: + if(sqlEditorUtils.previousStatus != status && + !$status_el.hasClass('fa-exclamation-triangle')) { + $status_el.removeClass() + .addClass('fa fa-exclamation-triangle'); + is_status_changed = true; + } + break; + default: + if(sqlEditorUtils.previousStatus != status && + !$status_el.hasClass('fa-query_tool_connected')) { + $status_el.removeClass() + .addClass('fa-custom fa-query-tool-connected'); + is_status_changed = true; + } + } + + sqlEditorUtils.previousStatus = status; + // Set bootstrap popover message + if(is_status_changed) { + $el.popover('hide'); + $el.attr('data-content', msg); + } + } else { + // We come here means we did not receive expected response + // from server, we need to error out + sqlEditorUtils.previousStatus = -99; + msg = gettext("Something went wrong, " + + "make sure you are logged into pgAdmin4."); + $el.attr('data-content', msg); + if(!$status_el.hasClass('fa-query-tool-disconnected')) { + $el.popover('hide'); + $status_el.removeClass() + .addClass('fa-custom fa-query-tool-disconnected'); + } + } + }, + error: function (e) { + sqlEditorUtils.previousStatus = -1; + var msg = gettext("Transaction status check failed."); + if (e.readyState == 0) { + msg = gettext("Not connected to the server or the connection to " + + "the server has been closed."); + } else if (e.responseJSON && e.responseJSON.errormsg) { + msg = e.responseJSON.errormsg; + } + + // Set bootstrap popover + $el.attr('data-content', msg); + // Add error class + if(!$status_el.hasClass('fa-query-tool-disconnected')) { + $el.popover('hide'); + $status_el.removeClass() + .addClass('fa-custom fa-query-tool-disconnected'); + } + } + }); + }, + // This function will update the connection status + updateConnectionStatus: function(url, poll_time) { + var $el = $(".connection_status"), + $status_el = $($($el).find(".fa-custom")); + + // Apply popover on element + $el.popover(); + + // To set initial connection status + sqlEditorUtils.fetchConnectionStatus(url, $el, $status_el); + + // Calling it again in specified interval + setInterval( + sqlEditorUtils.fetchConnectionStatus.bind(null, url, $el, $status_el), + poll_time * 1000 + ); } }; return sqlEditorUtils; diff --git a/web/pgadmin/tools/datagrid/__init__.py b/web/pgadmin/tools/datagrid/__init__.py index 6b1d699..19469eb 100644 --- a/web/pgadmin/tools/datagrid/__init__.py +++ b/web/pgadmin/tools/datagrid/__init__.py @@ -226,7 +226,7 @@ def panel(trans_id, is_query_tool, editor_title): # bgcolor = None fgcolor = None - if str(trans_id) in session['gridData']: + if 'gridData' in session and str(trans_id) in session['gridData']: # Fetch the object for the specified transaction id. # Use pickle.loads function to get the command object session_obj = session['gridData'][str(trans_id)] diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html index ff4368d..4229c20 100644 --- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html +++ b/web/pgadmin/tools/datagrid/templates/datagrid/index.html @@ -1,8 +1,5 @@ {% extends "base.html" %} {% block title %}{{ config.APP_NAME }} - Datagrid{% endblock %} -{% block css_link %} - -{% endblock %} {% block body %} connect diff --git a/web/pgadmin/tools/sqleditor/static/img/disconnect.svg b/web/pgadmin/tools/sqleditor/static/img/disconnect.svg new file mode 100644 index 0000000..113b758 --- /dev/null +++ b/web/pgadmin/tools/sqleditor/static/img/disconnect.svg @@ -0,0 +1 @@ +disconnect diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js index dbc416e..eb52cc4 100644 --- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js @@ -107,6 +107,8 @@ define('tools.querytool', [ filter = self.$el.find('#sql_filter'); $('.editor-title').text(_.unescape(self.editor_title)); + self.checkConnectionStatus(); + self.filter_obj = CodeMirror.fromTextArea(filter.get(0), { lineNumbers: true, mode: self.handler.server_type === "gpdb" ? "text/x-gpsql" : "text/x-pgsql", @@ -114,8 +116,12 @@ define('tools.querytool', [ widget: "\u2026" }, foldGutter: { - rangeFinder: CodeMirror.fold.combine(CodeMirror.pgadminBeginRangeFinder, CodeMirror.pgadminIfRangeFinder, - CodeMirror.pgadminLoopRangeFinder, CodeMirror.pgadminCaseRangeFinder) + rangeFinder: CodeMirror.fold.combine( + CodeMirror.pgadminBeginRangeFinder, + CodeMirror.pgadminIfRangeFinder, + CodeMirror.pgadminLoopRangeFinder, + CodeMirror.pgadminCaseRangeFinder + ) }, gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], extraKeys: pgBrowser.editor_shortcut_keys, @@ -405,6 +411,24 @@ define('tools.querytool', [ }); }, + // This function will check the connection status at specific + // interval defined by the user in preference + checkConnectionStatus: function() { + var self = this, + preference = window.top.pgAdmin.Browser.get_preference( + 'sqleditor', 'connection_status_fetch_time' + ); + if(!preference && self.handler.is_new_browser_tab) { + preference = window.opener.pgAdmin.Browser.get_preference( + 'sqleditor', 'connection_status_fetch_time' + ) + } + SqlEditorUtils.updateConnectionStatus( + url_for('sqleditor.connection_status', {'trans_id': self.transId}), + preference.value + ); + }, + /* To prompt user for unsaved changes */ user_confirmation: function (panel, msg) { // If there is anything to save then prompt user @@ -3283,8 +3307,7 @@ define('tools.querytool', [ // If status is True then poll the result. self._poll(); - } - else { + } else { self.trigger('pgadmin-sqleditor:loading-icon:hide'); self.disable_tool_buttons(false); $("#btn-cancel-query").prop('disabled', true); diff --git a/web/webpack.config.js b/web/webpack.config.js index 726c7f5..b989a4c 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -268,6 +268,12 @@ module.exports = { }, { test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file-loader?name=fonts/[name].[ext]', + include: [ + /node_modules/, + path.join(sourceDir, '/css/'), + path.join(sourceDir, '/scss/'), + path.join(sourceDir, '/fonts/'), + ], exclude: /vendor/, }, { test: /\.scss$/,